﻿using EmbeddedSensorCloud.Command;
using EmbeddedSensorCloud.Core;
using EmbeddedSensorCloud.Core.Plugin;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EmbeddedSensorCloud.Console.Commands
{
    public class PluginCommand : CommandBase
    {
        private readonly PluginCore worker;

        public PluginCommand(PluginCore worker)
        {
            if (worker == null)
            {
                throw new ArgumentException("PluginCore cannot be null");
            }

            this.worker = worker;
        }

        public override string Description
        {
            get { return "Load, unload or clear plugins."; }
        }

        public override string Name
        {
            get { return "plugin"; }
        }

        public override string Syntax
        {
            get { return "plugin [load <path> {args}] [unload <name>] [clear]"; }
        }

        protected override void execute(string[] param)
        {
            if (param == null || param.Length == 0)
            {
                throw new ArgumentException("Arguments cannot be null or empty");
            }

            if (param[0] == "clear")
            {
                int removed = this.worker.ClearPlugins();
                base.RaiseLogged(string.Format("{0} plugin(s) removed.", removed));
            }
            else if (param[0] == "load")
            {
                bool isFile = File.Exists(param[1]);
                if (isFile)
                {
                    string[] pluginArgs = new string[param.Length - 2];
                    Array.Copy(param, 2, pluginArgs, 0, pluginArgs.Length);
                    
                    try
                    {
                        var plugin = worker.AddPlugin(param[1], pluginArgs);
                        base.RaiseLogged(string.Format("Plugin '{0}' v{1} added.", plugin.Name, plugin.Version));
                    }
                    catch (PluginLoadException ex)
                    {
                        base.RaiseLogged(ex.ToString());
                    }
                    catch (PluginExistingException ex)
                    {
                        base.RaiseLogged(ex.ToString());
                    }
                    catch (PluginActivationException ex)
                    {
                        base.RaiseLogged(ex.ToString());
                    }
                    catch (PluginInitializationException ex)
                    {
                        base.RaiseLogged(ex.ToString());
                    }
                }
                else
                {
                    base.RaiseLogged("Invalid plugin file path");
                }
            }
            else if (param[0] == "unload")
            {
                bool isRemoved = worker.RemovePlugin(param[1]);
                if (isRemoved)
                {
                    base.RaiseLogged("Plugin removed.");
                }
                else
                {
                    base.RaiseLogged("Plugin not found");
                }
            }
        }

        public override string RequiredArgumentRegex
        {
            get { return "(load .+|unload .+|clear)"; }
        }
    }
}
